// Script Resource
// (c) jimon game studio

#ifndef JEH_JESCRIPTRESOURCE
#define JEH_JESCRIPTRESOURCE

#include "IResourceManager.h"

namespace je
{
	namespace media
	{
		//! Script Resource
		class jeScriptResource:public je::media::IResource
		{
		protected:
			core::IBuffer * Script;

		public:
			//! Constructor
			jeScriptResource(const jeStringc & ResourceName)
				:IResource(ResourceName),Script(NULL)
			{
			}

			//! Constructor
			jeScriptResource(const jeStringc & ResourceName,core::IBuffer * NewScript)
				:IResource(ResourceName,false),Script(NewScript)
			{
				Script->Grab();
			}

			//! Destructor
			~jeScriptResource()
			{
				if(Script)
					Script->Drop();
			}

			//! Get Script
			core::IBuffer * GetScript()
			{
				return Script;
			}

			//! Load Resource
			void Load()
			{
				core::IDataBase_Query * Query = GetResourceManager()->GetDataBase()->Query(jeStringc("SELECT * FROM ScriptResources WHERE Name = '")+CurrentResourceName+jeStringc("'"));
				Script = Query->GetFieldBuffer("Data");
				Query->Drop();
			}

			//! UnLoad Resource
			void UnLoad()
			{
				Script->Drop();
				Script = NULL;
			}

			//! Get Type Name
			virtual jeStringc GetTypeName()
			{
				return jeStringc("ScriptResource");
			}
		};

		//! Script Resource Factory
		class jeScriptResourceFactory:public je::media::IResourceFactory
		{
		protected:
			typedef jeMap<jeStringc,jeScriptResource*> ScriptMapType;
			ScriptMapType ScriptMap;
		public:

			//! Constructor
			jeScriptResourceFactory()
			{
			}

			//! Destructor
			~jeScriptResourceFactory()
			{
				ClearResources();
			}

			//! Add Resources
			void AddResources(IResource * Resource)
			{
				ScriptMap.set(Resource->GetName(),static_cast<jeScriptResource*>(Resource));
				Resource->Grab();
			}

			//! Load Resources
			void LoadResources()
			{
				ClearResources();

				core::IDataBase_Query * Query = GetResourceManager()->GetDataBase()->Query("SELECT * FROM ScriptResources");
				while(!Query->Eof())
				{
					jeStringc ResourceName = Query->GetFieldjeStringc("Name");
					jeScriptResource * ScriptResource = NULL;
					JENEW(ScriptResource,jeScriptResource(ResourceName))
					ScriptMap.set(ResourceName,ScriptResource);
					Query->NextRow();
				}
				Query->Drop();
			}

			//! Clear Resources
			void ClearResources()
			{
				for(ScriptMapType::Iterator Iter = ScriptMap.getIterator();!Iter.atEnd();Iter++)
					Iter->getValue()->Drop();
				ScriptMap.clear();
			}

			//! Return Resource
			IResource * GetResource(const jeStringc & ResourceName)
			{
				ScriptMapType::Node * Node = ScriptMap.find(ResourceName);
				if(Node)
					return Node->getValue();
				else
					return NULL;
			}

			//! Return Resource Type
			jeStringc GetResourceType()
			{
				return jeStringc("ScriptResource");
			}

			//! Garbage Collector
			void GarbageCollector()
			{
				for(ScriptMapType::Iterator Iter = ScriptMap.getIterator();!Iter.atEnd();Iter++)
					if(Iter->getValue()->IsNeedToUnload())
						Iter->getValue()->GarbageUnload();
			}
		};
	}
}

#define JE_SCRIPTRESOURCE( __Name ) JE_RESOURCEBASE_GET(__Name,ScriptResource)

#endif
